﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using _80X_CG_Frame.Utils;
using _80X_CG_Frame.Workers;
using Newtonsoft.Json.Linq;

namespace _80X_CG_Frame.Objects
{
     public class SFC : AsyncClient
    {
        private WebApiUtil 过站报告API;
        private WebApiUtil 参数上传API;
        private WebApiUtil 上料确认API;
        private long serial_no = 1;
        private StreamWriter 返回结果文件;
        private StreamWriter 焊接参数文件;

        private string 私有的过站报告地址;
        private string 私有的上料确认地址;
        private string 私有的参数上传地址;
        private int timeout = 1000;

        public SFC(string 过站报告_uri, string 上料确认_uri, string 参数上传_uri, int timeout = 1000)
        {
            this.timeout = timeout;
            过站报告地址 = 过站报告_uri;
            上料确认地址 = 上料确认_uri;
            参数上传地址 = 参数上传_uri;
            //过站报告API = new WebApiUtil(过站报告_uri, timeout);
            //上料确认API = new WebApiUtil(上料确认_uri, timeout);
            //参数上传API = new WebApiUtil(参数上传_uri, timeout);


            //初始化文件夹
            string history_data_folder = GLOBAL.config.Get("history_data_folder");
            string 返回结果文件夹 = history_data_folder + @"\returns";
            string 焊接参数文件夹 = history_data_folder + @"\datas";

            if (!Directory.Exists(返回结果文件夹))
                Directory.CreateDirectory(返回结果文件夹);
            if (!Directory.Exists(焊接参数文件夹))
                Directory.CreateDirectory(焊接参数文件夹);

            string 返回结果文件路径 = 返回结果文件夹 + @"\" + GLOBAL.GetMondayDate(DateTime.Now).ToString("yyyyMMdd") + "-"
                + GLOBAL.GetSundayDate(DateTime.Now).ToString("yyyyMMdd") + @".log";
            //string warning_file_path = warning_folder_path + @"\" + DateTime.Now.ToString("yyyyMMdd HH-mm-ss") + @".csv";
            返回结果文件 = new StreamWriter(返回结果文件路径, true)
            {
                AutoFlush = true
            };

            string 焊接参数文件路径 = 焊接参数文件夹 + @"\" + GLOBAL.GetMondayDate(DateTime.Now).ToString("yyyyMMdd") + "-"
                + GLOBAL.GetSundayDate(DateTime.Now).ToString("yyyyMMdd") + @".log";
            //string warning_file_path = warning_folder_path + @"\" + DateTime.Now.ToString("yyyyMMdd HH-mm-ss") + @".csv";
            焊接参数文件 = new StreamWriter(焊接参数文件路径, true)
            {
                AutoFlush = true
            };
        }

        ~SFC()
        {
            try
            {
                返回结果文件.Close();
                焊接参数文件.Close();

            }
            catch(Exception e)
            {
                Console.WriteLine(e.ToString());
            }
        }
        Dictionary<process_name, string> process_dic = new Dictionary<process_name, string>()
        {
            {process_name.Frame签收,  "13904144"},
            {process_name.螺母焊接,  "13602611"}
        };
        public string 流水号
        {
            get
            {
                var value = serial_no.ToString("D6");
                serial_no++;
                if (serial_no > 999999)
                {
                    serial_no = 1;
                }
                return value;
            }
        }

        /// <summary>
        /// 当地址发生变动时将会更新api
        /// </summary>
        public string 过站报告地址 {
            get => 私有的过站报告地址;
            set 
            {
                if(私有的过站报告地址 != value)
                    过站报告API = new WebApiUtil(value, timeout);

                私有的过站报告地址 = value;
            }
        }

        /// <summary>
        /// 当地址发生变动时将会更新api
        /// </summary>
        public string 上料确认地址
        {
            get => 私有的上料确认地址;
            set
            {
                if (私有的上料确认地址 != value)
                    上料确认API = new WebApiUtil(value, timeout);

                私有的上料确认地址 = value;
            }
        }

        /// <summary>
        /// 当地址发生变动时将会更新api
        /// </summary>
        public string 参数上传地址
        {
            get => 私有的参数上传地址;
            set
            {
                if (私有的参数上传地址 != value)
                    参数上传API = new WebApiUtil(value, timeout);

                私有的参数上传地址 = value;
            }
        }

        public async Task<bool> 上料确认(JObject data, int retry = 3)
        {
            var result = false;
            try
            {
                for (int i = 0; i < retry; i++)
                {
                    try
                    {
                        string ip = (string)data["host_ip"];
                        data["request_id"] = ip.Replace(".", "") + DateTime.Now.ToString("yyyyMMddHHmmss") + 流水号;
                        var respond = await 上料确认API.PostRequestAsync(data);
                        var 上料确认结果 = JObject.Parse(await WebApiUtil.GetResponseStringAsync(respond));
                        Console.WriteLine("上料确认" + 上料确认结果.ToString());
                        JToken jToken;

                        if (上料确认结果.TryGetValue("rc", out jToken))
                        {
                            if ((string)jToken != "000")
                            {
                                //Console.WriteLine("绑码结果" + (string)绑码结果["rm"]);
                                Log.Write((string)data["prod_code"] + "上料确认结果:" + (string)上料确认结果["rm"]);
                                result = false;
                            }
                            else
                                result = true;
                        }
                        返回结果文件.WriteLine(DateTime.Now.ToString("[HH:mm:ss]") + (string)data["prod_code"] + "上料确认结果\r\n" + 上料确认结果.ToString());
                        break;
                    }
                    catch (TaskCanceledException e)
                    {
                        Console.WriteLine("第" + (i + 1) + "次上料确认请求失败");
                        Console.WriteLine(e.Message);
                    }

                }
            }
            catch (Exception e)
            {
                Console.WriteLine(e.ToString());
                return false;
            }
            return result;
        }
        public async Task<bool> 过站签收(JObject data, int retry = 3, process_name p = process_name.Frame签收)
        {
            var result = false;
            try
            {
                string ip = (string)data["host_ip"];
                for (int i = 0; i < retry; i++)
                {
                    try
                    {
                        data["request_id"] = ip.Replace(".", "") + DateTime.Now.ToString("yyyyMMddHHmmss") + 流水号;
                        data["work_action"] = "簽收";
                        data["work_type"] = "sign";
                        data["process_name"] = process_dic[p];
                        data["start_time"] = DateTime.Now.ToString("yyyyMMddHHmmss");
                        data["end_time"] = DateTime.Now.ToString("yyyyMMddHHmmss");

                        var respond = await 过站报告API.PostRequestAsync(data);
                        var 签收结果 = JObject.Parse(await WebApiUtil.GetResponseStringAsync(respond));
                        Console.WriteLine("签收结果" + 签收结果.ToString());
                        JToken jToken;

                        if (签收结果.TryGetValue("rc", out jToken))
                        {
                            if ((string)jToken != "000")
                            {
                                //Console.WriteLine("签收结果" + (string)签收结果["rm"]);
                                Log.Write((string)data["prod_barcode"] + "签收结果:" + (string)签收结果["rm"]);

                                result = false;
                            }
                            else
                                result = true;
                        }
                        返回结果文件.WriteLine(DateTime.Now.ToString("[HH:mm:ss]") + (string)data["prod_barcode"] + "签收结果\r\n" + 签收结果.ToString());
                        break;
                    }
                    catch (TaskCanceledException e)
                    {
                        Console.WriteLine("第" + (i + 1) + "次签收请求失败");
                        Console.WriteLine(e.Message);
                    }

                }
                
            }
            catch (Exception e)
            {
                Console.WriteLine(e.ToString());
                return false;
            }
            return result;
        }
        public async Task<bool> 过站绑码(JObject data, int retry = 3)
        {
            var result = false;
            try
            {
                string ip = (string)data["host_ip"];
                
                for (int i = 0; i < retry; i++)
                {
                    try
                    {
                        data["request_id"] = ip.Replace(".", "") + DateTime.Now.ToString("yyyyMMddHHmmss") + 流水号;
                        data["work_action"] = "綁碼";
                        data["work_type"] = "bing";
                        data["start_time"] = DateTime.Now.ToString("yyyyMMddHHmmss");
                        data["end_time"] = DateTime.Now.ToString("yyyyMMddHHmmss");
                        data["process_name"] = "32312964";

                        var respond = await 过站报告API.PostRequestAsync(data);
                        var 绑码结果 = JObject.Parse(await WebApiUtil.GetResponseStringAsync(respond));
                        Console.WriteLine("绑码结果" + 绑码结果.ToString());

                        JToken jToken;

                        if (绑码结果.TryGetValue("rc", out jToken))
                        {
                            if ((string)jToken != "000")
                            {
                                //Console.WriteLine("绑码结果" + (string)绑码结果["rm"]);
                                Log.Write((string)data["prod_barcode"] + "绑码结果:" + (string)绑码结果["rm"]);
                                result = false;
                            }
                            else
                                result = true;
                        }
                        返回结果文件.WriteLine(DateTime.Now.ToString("[HH:mm:ss]") + (string)data["prod_barcode"] + "绑码结果\r\n" + 绑码结果.ToString());
                        break;
                    }
                    catch (TaskCanceledException e)
                    {
                        Console.WriteLine("第" + (i + 1) + "次绑码请求失败");
                        Console.WriteLine(e.Message);
                    }
                    
            }
            }
            catch (Exception e)
            {
                Console.WriteLine(e.ToString());
                return false;
            }
            return result;
        }
        public async Task<bool> 参数上传(JObject data, int retry = 3)
        {
            var result = false;
            try
            {
                string ip = (string)data["host_ip"];

                for (int i = 0; i < retry; i++)
                {
                    try
                    {
                        data["request_id"] = ip.Replace(".", "") + DateTime.Now.ToString("yyyyMMddHHmmssfff") + 流水号;
                        data["start_time"] = DateTime.Now.ToString("yyyyMMddHHmmss");
                        data["end_time"] = DateTime.Now.ToString("yyyyMMddHHmmss");

                        var respond = await 参数上传API.PostRequestAsync(data);
                        var 参数上传结果 = JObject.Parse(await WebApiUtil.GetResponseStringAsync(respond));
                        Console.WriteLine("参数上传结果" + 参数上传结果.ToString());

                        JToken jToken;

                        if (参数上传结果.TryGetValue("rc", out jToken))
                        {
                            if ((string)jToken != "000")
                            {
                                //Console.WriteLine("绑码结果" + (string)绑码结果["rm"]);
                                Log.Write((string)data["prod_barcode"] + "参数上传结果:" + (string)参数上传结果["rm"]);
                                result = false;
                            }
                            else
                                result = true;
                        }
                        焊接参数文件.WriteLine(DateTime.Now.ToString("[HH:mm:ss]") + data.ToString());
                        焊接参数文件.WriteLine(DateTime.Now.ToString("[HH:mm:ss]") + (string)data["frame_barcode"] + "参数上传结果\r\n" + 参数上传结果.ToString());
                        break;
                    }
                    catch (TaskCanceledException e)
                    {
                        Console.WriteLine("第" + (i + 1) + "次参数上传请求失败");
                        Console.WriteLine(e.Message);
                    }

                }
            }
            catch (Exception e)
            {
                Console.WriteLine(e.ToString());
                return false;
            }
            return result;
        }

        public bool 同步上料确认(JObject data, int retry = 3)
        {
            var result = false;
            try
            {
                for (int i = 0; i < retry; i++)
                {
                    try
                    {
                        string ip = (string)data["host_ip"];
                        data["request_id"] = ip.Replace(".", "") + DateTime.Now.ToString("yyyyMMddHHmmss") + 流水号;
                        var respond = WebApiUtil.PostRequest(data, 上料确认地址);
                        var 上料确认结果 = JObject.Parse(respond);
                        Console.WriteLine("上料确认" + 上料确认结果.ToString());
                        JToken jToken;

                        if (上料确认结果.TryGetValue("rc", out jToken))
                        {
                            if ((string)jToken != "000")
                            {
                                //Console.WriteLine("绑码结果" + (string)绑码结果["rm"]);
                                Log.Write((string)data["prod_code"] + "上料确认结果:" + (string)上料确认结果["rm"]);
                                Log.Write("request_id = " + (string)data["request_id"]);
                                result = false;
                            }
                            else
                                result = true;
                        }
                        返回结果文件.WriteLine(DateTime.Now.ToString("[HH:mm:ss]") + (string)data["prod_code"] + "上料确认结果\r\n" + 上料确认结果.ToString());
                        break;
                    }
                    catch (Exception e)
                    {
                        Console.WriteLine("第" + (i + 1) + "次上料确认请求失败");
                        Console.WriteLine(e.Message);
                    }

                }
            }
            catch (Exception e)
            {
                Console.WriteLine(e.ToString());
                return false;
            }
            return result;
        }
        public bool 同步过站签收(JObject data, int retry = 3, process_name p = process_name.Frame签收)
        {
            var result = false;
            try
            {
                string ip = (string)data["host_ip"];
                for (int i = 0; i < retry; i++)
                {
                    try
                    {
                        data["request_id"] = ip.Replace(".", "") + DateTime.Now.ToString("yyyyMMddHHmmss") + 流水号;
                        data["work_action"] = "簽收";
                        data["work_type"] = "sign";
                        data["process_name"] = process_dic[p];
                        data["start_time"] = DateTime.Now.ToString("yyyyMMddHHmmss");
                        data["end_time"] = DateTime.Now.ToString("yyyyMMddHHmmss");

                        var respond = WebApiUtil.PostRequest(data, 过站报告地址);
                        var 签收结果 = JObject.Parse(respond);
                        Console.WriteLine("签收结果" + 签收结果.ToString());
                        JToken jToken;

                        if (签收结果.TryGetValue("rc", out jToken))
                        {
                            if ((string)jToken != "000")
                            {
                                //Console.WriteLine("签收结果" + (string)签收结果["rm"]);
                                Log.Write((string)data["prod_barcode"] + "签收结果:" + (string)签收结果["rm"]);

                                result = false;
                            }
                            else
                                result = true;
                        }
                        返回结果文件.WriteLine(DateTime.Now.ToString("[HH:mm:ss]") + (string)data["prod_barcode"] + "签收结果\r\n" + 签收结果.ToString());
                        break;
                    }
                    catch (Exception e)
                    {
                        Console.WriteLine("第" + (i + 1) + "次签收请求失败");
                        Console.WriteLine(e.Message);
                    }

                }

            }
            catch (Exception e)
            {
                Console.WriteLine(e.ToString());
                return false;
            }
            return result;
        }
        public bool 同步过站绑码(JObject data, int retry = 3)
        {
            var result = false;
            try
            {
                string ip = (string)data["host_ip"];

                for (int i = 0; i < retry; i++)
                {
                    try
                    {
                        data["request_id"] = ip.Replace(".", "") + DateTime.Now.ToString("yyyyMMddHHmmss") + 流水号;
                        data["work_action"] = "綁碼";
                        data["work_type"] = "bing";
                        data["start_time"] = DateTime.Now.ToString("yyyyMMddHHmmss");
                        data["end_time"] = DateTime.Now.ToString("yyyyMMddHHmmss");
                        data["process_name"] = "13602611";

                        var respond = WebApiUtil.PostRequest(data, 过站报告地址);
                        var 绑码结果 = JObject.Parse(respond);
                        Console.WriteLine("绑码结果" + 绑码结果.ToString());

                        JToken jToken;

                        if (绑码结果.TryGetValue("rc", out jToken))
                        {
                            if ((string)jToken != "000")
                            {
                                //Console.WriteLine("绑码结果" + (string)绑码结果["rm"]);
                                Log.Write((string)data["prod_barcode"] + "绑码结果:" + (string)绑码结果["rm"]);
                                result = false;
                            }
                            else
                                result = true;
                        }
                        返回结果文件.WriteLine(DateTime.Now.ToString("[HH:mm:ss]") + (string)data["prod_barcode"] + "绑码结果\r\n" + 绑码结果.ToString());
                        break;
                    }
                    catch (Exception e)
                    {
                        Console.WriteLine("第" + (i + 1) + "次绑码请求失败");
                        Console.WriteLine(e.Message);
                    }

                }
            }
            catch (Exception e)
            {
                Console.WriteLine(e.ToString());
                return false;
            }
            return result;
        }
        public bool 同步参数上传(JObject data, int retry = 3)
        {
            var result = false;
            try
            {
                string ip = (string)data["host_ip"];

                for (int i = 0; i < retry; i++)
                {
                    try
                    {
                        data["request_id"] = ip.Replace(".", "") + DateTime.Now.ToString("yyyyMMddHHmmssfff") + 流水号;
                        data["start_time"] = DateTime.Now.ToString("yyyyMMddHHmmss");
                        data["end_time"] = DateTime.Now.ToString("yyyyMMddHHmmss");

                        var respond = WebApiUtil.PostRequest(data, 参数上传地址);
                        var 参数上传结果 = JObject.Parse(respond);
                        Console.WriteLine("参数上传结果" + 参数上传结果.ToString());

                        JToken jToken;

                        if (参数上传结果.TryGetValue("rc", out jToken))
                        {
                            if ((string)jToken != "000")
                            {
                                //Console.WriteLine("绑码结果" + (string)绑码结果["rm"]);
                                Log.Write((string)data["prod_barcode"] + "参数上传结果:" + (string)参数上传结果["rm"]);
                                result = false;
                            }
                            else
                                result = true;
                        }
                        焊接参数文件.WriteLine(DateTime.Now.ToString("[HH:mm:ss]") + data.ToString());
                        焊接参数文件.WriteLine(DateTime.Now.ToString("[HH:mm:ss]") + (string)data["frame_barcode"] + "参数上传结果\r\n" + 参数上传结果.ToString());
                        break;
                    }
                    catch (Exception e)
                    {
                        Console.WriteLine("第" + (i + 1) + "次参数上传请求失败");
                        Console.WriteLine(e.Message);
                    }

                }
            }
            catch (Exception e)
            {
                Console.WriteLine(e.ToString());
                return false;
            }
            return result;
        }
        public void 更新地址(string 过站报告_uri, string 上料确认_uri, string 参数上传_uri, int timeout = 1000)
        {
            this.timeout = timeout;
            过站报告地址 = 过站报告_uri;
            上料确认地址 = 上料确认_uri;
            参数上传地址 = 参数上传_uri;
        }
        
    }

    public enum process_name
    {
        螺母焊接,
        Frame签收
    }
}
